<?php

namespace support;

class Request
{
    protected $server = [];
    protected $get = null;
    protected $post = null;
    protected $files = null;
    protected $cookie = null;
    protected $header = [];
    protected $session = [];

    public function __construct()
    {
        $this->server = $_SERVER ?? [];
        $this->get = $_GET ?? [];
        $this->post = $_POST ?? []; // filter_input_array(INPUT_POST)
        $this->cookie = $_COOKIE ?? [];
        $this->session = $_SESSION ?? [];

        foreach ($this->server as $key => $val) {
            if (0 === strpos($key, 'HTTP_')) {
                $key          = str_replace('_', '-', strtolower(substr($key, 5)));
                $this->header[$key] = $val;
            }
        }
    }

    protected $mimeType = [
        'json'  => 'application/json,text/x-json,application/jsonrequest,text/json',
        'html'  => 'text/html,application/xhtml+xml,*/*',
        'text'  => 'text/plain',

        'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*',
        'js'    => 'text/javascript,application/javascript,application/x-javascript',
        'css'   => 'text/css',
        'csv'   => 'text/csv',
        'pdf'   => 'application/pdf',
        'rss'   => 'application/rss+xml',
        'xml'   => 'application/xml,text/xml,application/x-xml',
        'yaml'  => 'application/x-yaml,text/yaml',
        'atom'  => 'application/atom+xml',
    ];


    public function type(): string
    {
        $accept = $this->server('HTTP_ACCEPT');

        if (empty($accept)) {
            return '';
        }
        foreach ($this->mimeType as $key => $val) {
            $array = explode(',', $val);
            foreach ($array as $k => $v) {
                if (stristr($accept, $v)) {
                    return $key;
                }
            }
        }
        return '';
    }

    public function isJson(): bool
    {
        $acceptType = $this->type();
        return false !== strpos($acceptType, 'json');
    }

    public function method()
    {
        return $this->server('REQUEST_METHOD') ?: 'GET';
    }

    public function header(string $name = '', string $default = '')
    {
        if (!$name) {
            return $this->header;
        }

        $name = str_replace('_', '-', strtolower($name));
        return $this->header[$name] ?? $default;
    }

    public function server(string $name = '', string $default = '')
    {
        if (!$name) {
            return $this->server;
        }
        $name = strtoupper($name);
        return $this->server[$name] ?? $default;
    }

    function cookie(string $name = '', string $default = '')
    {
        if (!$name) {
            return $this->cookie;
        }
        return $this->cookie[$name] ?? $default;
    }

    /**
     * @return null|UploadFile|UploadFile[]
     */
    function file($name = '')
    {
        if (is_null($this->files)) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            foreach ($_FILES as $key => $file) {
                // $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
                $mimeType = finfo_file($finfo, $file['tmp_name']);
                $this->files[$key] = new UploadFile($file['tmp_name'], $file['name'], $mimeType, $file['error']);
            }
            finfo_close($finfo);
        }
        if (!$name) {
            return $this->files;
        }
        return $this->files[$name] ?? null;
    }

    function get(string $name = '', string $default = '')
    {
        if (!$name) {
            return $this->get;
        }
        return $this->get[$name] ?? $default;
    }

    function post(string $name = '', string $default = '')
    {
        if (!$name) {
            return $this->post;
        }
        return $this->post[$name] ?? $default;
    }

    function input(string $name = '', string $default = '')
    {
        $list = $this->get() + $this->post();
        return $list[$name] ?? $default;
    }

    function all()
    {
        return $this->get() + $this->post();
    }

    function more($params = [], $needList = false)
    {
        $data = $this->all();
        if (!$params) {
            return $data;
        }
        $res = [];
        foreach ($params as $index => $param) {
            $default = '';
            if (is_string($index)) { // 字典
                $key = $index;
                $default = $param;
            } else {
                if (!is_array($param)) {
                    $key = $param;
                } else {
                    $key = $param[0];
                    $default = $param[1] ?? '';
                }
            }

            $value = $data[$key] ?? $default;
            $type = gettype($default);
            if ($type !== gettype($value)) {
                switch ($type) {
                    case 'string':
                        $value = (string)$value;
                        break;
                    case 'integer':
                        $value = (int)$value;
                        break;
                    case 'double':
                        $value = (float)$value;
                        break;
                    case 'boolean':
                        $value = !!$value;
                        break;
                    case 'array':
                        $value = [$value];
                        break;
                }
            }

            if ($needList) {
                $res[] = $value;
            } else {
                $res[$key] = $value;
            }
        }
        return $res;
    }
}
